package com.wlyuan.open.domain.service.yuhong;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wlyuan.open.domain.PushBusinessType;
import com.wlyuan.open.domain.PushTask;
import com.wlyuan.open.domain.repository.PushTaskRepository;
import com.wlyuan.open.domain.service.PushStrategy;
import com.wlyuan.open.vo.push.order.OrderDetailVO;
import com.wlyuan.open.vo.push.order.OrderGoodsVO;
import com.wlyuan.open.vo.push.track.TrackDetailVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author 东方雨虹推送
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class YuHongPushStrategy implements PushStrategy {

    private final PushTaskRepository pushTaskRepository;


    @Override
    public void handle(PushTask pushTask) {
        //根据业务类型，判断请求数据
        var businessType = pushTask.getBusinessType();
        if (businessType.equals(PushBusinessType.ORDER_SIGNED)) {
            orderSign(pushTask);
        } else {
            orderTrack(pushTask);
        }
        pushTaskRepository.save(pushTask);
    }

    /**
     * 时间转化
     * @param date
     * @return
     */
    private Date parseDate(LocalDateTime date){
        String dateFormat = "yyyy-MM-dd HH:mm:ss";
        String dateStr = DateUtil.format(date,dateFormat);
        Date newDate = DateUtil.parse(dateStr,dateFormat);
        return newDate;
    }

    private boolean notNullInteger(Integer integer){
        if(integer!=null && integer > 0){
            return true;
        }
        return false;
    }

    private YuHongSignRequest signAssemble(PushTask pushTask){

        var orderDetail = pushTask.getBusinessInfo().toJavaObject(OrderDetailVO.class);
        YuHongSignRequest signRequest = new YuHongSignRequest();
        signRequest.setPactCode(orderDetail.getContractNo());
        signRequest.setStatusName(orderDetail.getStatusName());
        signRequest.setCustomerName(orderDetail.getCustomerName());
        signRequest.setFromMan(orderDetail.getFromAddress().getContactName());
        signRequest.setFromContact(orderDetail.getFromAddress().getContactMobile());
        signRequest.setFromTime(parseDate(orderDetail.getFromTime()));
        signRequest.setEndUserName(orderDetail.getConsigneeName());
        signRequest.setToMan(orderDetail.getToAddress().getContactName());
        signRequest.setToContact(orderDetail.getToAddress().getContactMobile());
        signRequest.setToTime(parseDate(orderDetail.getToTime()));
        signRequest.setSignTypeName(orderDetail.getSign().getSignTypeName());
        signRequest.setSignTime(parseDate(orderDetail.getSignTime()));
        signRequest.setTotalAmount(new BigDecimal(orderDetail.getTotalQuantity().toString()));
        signRequest.setSignTotalAmount(new BigDecimal(orderDetail.getSign().getQuantity().toString()));
        signRequest.setSignExTotalAmount(orderDetail.getSign().getExceptionQuantity());
        signRequest.setReceiptTotalAmount(new BigDecimal("0"));
        signRequest.setReceiptExTotalAmount(new BigDecimal("0"));
        signRequest.setSignDesc(orderDetail.getSign().getRemarks());
        // TODO 回单说明是否是该字段
        signRequest.setReceiptDesc("");

        signRequest.setFromAddress(orderDetail.getFromAddress().getAddress());
        signRequest.setToAddress(orderDetail.getToAddress().getAddress());
        Optional.ofNullable(orderDetail.getEcho()).ifPresent(obj -> {
            signRequest.setEcho(JSONUtil.parseObj(orderDetail.getEcho()));
        });
        List<OrderGoodsVO> tmsOrderGoodsDTOS = orderDetail.getGoodsList();
        List<YuHongSignRequest.SignGoodDetail> signRequestGoodsList = new ArrayList<>(tmsOrderGoodsDTOS.size());
        tmsOrderGoodsDTOS.forEach(goods -> {
            YuHongSignRequest.SignGoodDetail signRequestGoods = signRequest.new SignGoodDetail();
            signRequestGoods.setName(goods.getName());
            signRequestGoods.setSpc(goods.getSpec());
            signRequestGoods.setAmount(new BigDecimal(goods.getQuantity()));
            signRequestGoods.setSignAmount(new BigDecimal(goods.getSign().getQuantity()));
            StringBuilder signExTypeNameStr = new StringBuilder();
            if (notNullInteger(goods.getSign().getDamageQuantity())) {
                signExTypeNameStr.append("破损数量：").append(goods.getSign().getDamageQuantity());
            }
            if (notNullInteger(goods.getSign().getLoseQuantity())) {
                signExTypeNameStr.append("丢失数量：").append(goods.getSign().getLoseQuantity());
            }
            if (notNullInteger(goods.getSign().getLackQuantity())) {
                signExTypeNameStr.append("缺少数量：").append(goods.getSign().getLackQuantity());
            }
            if (notNullInteger(goods.getSign().getOtherQuantity())) {
                signExTypeNameStr.append("其他数量：").append(goods.getSign().getOtherQuantity());
            }
            signRequestGoods.setSignExTypeName(signExTypeNameStr.toString());
            signRequestGoods.setSignExAmount(new BigDecimal(goods.getSign().getExceptionQuantity().toString()));
            signRequestGoods.setSignExDesc(goods.getSign().getRemarks());
            signRequestGoods.setReceiptAmount(new BigDecimal("0"));
            signRequestGoods.setReceiptExAmount(new BigDecimal("0"));
            StringBuilder receiptTypeNameStr = new StringBuilder();
            signRequest.setReceiptTotalAmount(new BigDecimal("0"));
            signRequest.setReceiptExTotalAmount(new BigDecimal("0"));
            signRequestGoods.setReceiptExTypeName(receiptTypeNameStr.toString());
            signRequestGoods.setReceiptExDesc("");
            Optional.ofNullable(goods.getEcho()).ifPresent(obj -> {
                signRequestGoods.setEcho(JSONUtil.parseObj(goods.getEcho()));
            });
            signRequestGoodsList.add(signRequestGoods);
        });
        signRequest.setDetails(signRequestGoodsList);
        pushTask.setRequestBody(JSONUtil.toJsonStr(signRequest));
        return signRequest;
    }

    private void orderSign(PushTask pushTask) {
        String requestJson = "";
        String responseData = "";
        StringBuilder url = new StringBuilder();
        try {
            YuHongSignRequest signRequest = signAssemble(pushTask);
            Map<String, Object> param = new HashMap<>();
            param.put("xmldata", new HashMap() {{
                put("header", new ArrayList() {{
                    add(signRequest);
                }});
            }});
            requestJson = JSONUtil.toJsonStr(param);
            url.append(pushTask.getRequestUrl());
            url.append("client_db=FLUXTMSDB");
            url.append("&client_customerid=FLUXTMSWLY");
            url.append("&messageid=GETORDERSIGN");
            //url.append("&appkey=" + yuhongAppkey;
            url.append("&timestamp=" + DateUtil.formatDateTime(new Date()));
            //url.append("&sign=" + URLEncoder.encode(buildSign(requestJson).toUpperCase(), "utf-8");
            url.append("&format=json");
            HttpRequest post = HttpRequest.post(url.toString());
            logger.info("url:===={}",url.toString());
            post.header("Content-Type", "application/json");
            post.body(requestJson);
            HttpResponse response = post.execute();
            responseData = response.body();
            boolean isSuccess = false;
            if (response.isOk()) {
                JSONObject data = JSONUtil.parseObj(response.body());
                if (data != null) {
                    data = (JSONObject) data.get("Response");
                }
                if (data != null) {
                    data = (JSONObject) data.get("return");
                }
                if ("1".equals(data.get("returnFlag"))) {
                    isSuccess = true;
                    pushTask.success(url.toString(),requestJson,data.toJSONString(1));
                }
            }
            if(!isSuccess){
                pushTask.fail(url.toString(),requestJson,response.body(),"东方雨虹推送失败");
            }
        } catch (Exception e) {
            logger.error("雨虹签收推送失败：",e);
            pushTask.fail(url.toString(),requestJson,responseData ,"东方雨虹推送失败"+e.getMessage());
        }
    }

    private String trackStatus(PushTask pushTask){
        String trackStatus = "";
        if(pushTask.getBusinessType().equals(PushBusinessType.TRACK_SET_OUT)){
            trackStatus = "T50";
        }else if(pushTask.getBusinessType().equals(PushBusinessType.TRACK_PRE_REACH)){
            trackStatus = "T60";
        }else if(pushTask.getBusinessType().equals(PushBusinessType.TRACK_REACH)){
            trackStatus = "T70";
        }else if(pushTask.getBusinessType().equals(PushBusinessType.TRACK_LOW_BATTERY)){
            trackStatus ="T52";
        }else if(pushTask.getBusinessType().equals(PushBusinessType.TRACK_LONG_STAY)){
            trackStatus ="T55";
        }
        return trackStatus;
    }

    
    private YuHongTrackRequest trackAssemble(PushTask pushTask){
        var track = pushTask.getBusinessInfo().toJavaObject(TrackDetailVO.class);
        YuHongTrackRequest YuHongTrackRequest = new YuHongTrackRequest();
        YuHongTrackRequest.setOrderNo(track.getContractNo());
        /**
         * todo 车辆信息
         */
        //YuHongTrackRequest.setVehiclePlateNo(orderIndexDTO.getCarSn());
        //YuHongTrackRequest.setDriverTel(orderIndexDTO.getDriverPhone());
        //YuHongTrackRequest.setDriverName(orderIndexDTO.getDriverName());
        YuHongTrackRequest.setTrackingTime(DateUtil.format(track.getTime(),"yyyy-MM-dd HH:mm:ss"));
        YuHongTrackRequest.setTrackingDescr(track.getTrackingDesc());
        YuHongTrackRequest.setTrackingStatus(trackStatus(pushTask));
        YuHongTrackRequest.setAddress(track.getAddress());
        YuHongTrackRequest.setLongitude(new BigDecimal(track.getLongitude()));
        YuHongTrackRequest.setLatitude(new BigDecimal(track.getLatitude()));
        YuHongTrackRequest.setUdf01("WLYUAN");
        pushTask.setRequestBody(JSONUtil.toJsonStr(YuHongTrackRequest));
        return YuHongTrackRequest;
    }


    
    
    private void orderTrack(PushTask pushTask){
        StringBuilder url= new StringBuilder("");
        String responseData ="";
        String requestJson="";
        try {
            YuHongTrackRequest YuHongTrackRequest = trackAssemble(pushTask);

            Map<String, Object> param = new HashMap<>();
            param.put("xmldata", new HashMap() {{
                put("header", new ArrayList() {{
                    add(YuHongTrackRequest);
                }});
            }});

            requestJson = JSONUtil.toJsonStr(param);
            url.append(pushTask.getRequestUrl());
            //url+="client_db=FLUXTMSDB";
            //url+="&client_customerid=FLUXTMSWLY";
            url.append("&messageid=GETCARRIEROT");
            //url+="&appkey="+yuhongAppkey;
            //url+="&timestamp="+DateUtil.formatDateTime(new Date());
            //url.append("&sign=" + URLEncoder.encode(buildSign(requestJson).toUpperCase(), "utf-8");
            url.append("&format=json");
            logger.info("url:======={}",url);
            HttpRequest post = HttpRequest.post(url.toString());
            post.header("Content-Type", "application/json");
            post.body(requestJson);
            HttpResponse response = post.execute();
            boolean isSuccess = false;
            responseData = response.body();
            if (response.isOk()) {
                JSONObject data = JSONUtil.parseObj(response.body());
                if (data != null) {
                    data = (JSONObject) data.get("Response");
                }
                if (data != null) {
                    data = (JSONObject) data.get("return");
                }
                if ("1".equals(data.get("returnFlag"))) {
                    isSuccess = true;
                    pushTask.success(url.toString(),requestJson,data.toJSONString(1));
                }
            }
            if(!isSuccess){
                pushTask.fail(url.toString(),requestJson,response.body(),"东方雨虹轨迹推送失败");
            }
        } catch (Exception e) {
            logger.error("东方雨虹轨迹推送失败:{}",e);
            pushTask.fail(url.toString(),requestJson,responseData,"东方雨虹轨迹推送失败"+e.getMessage());
        }
    }


}
